(in-package :skymech)

(defclass body ()
  ((vis  :accessor vis)
   (pos  :accessor pos)
   (vel  :accessor vel)
   (mass :accessor mass)))

(defun x (vec)
    (realpart vec))

(defun y (vec)
    (imagpart vec))

(defun sq (n)
    (* n n n))

(defun norm (vec)
    (/ vec
       (abs vec)))

(defmethod distance ((a body) (b body))
    (abs (- (pos a)
            (pos b))))

(defmethod gravitation ((a body) (b body))
    (/ (* (mass a)
          (mass b))
       (sq (distance a b))))

(defun update-vel! (M S &optional (dt 1.0))
    (let ((dVm (* (/ (gravitation M S)
                    (mass M))
                 dt
                 (norm (- (pos S)
                          (pos M))))))

        (setf (vel M) (+ (vel M)
                         dVm))))

(defun move-body! (M &optional (dt 1.0))
    (setf (pos M) (+ (pos M)
                     (* (vel M) dt))))
    
(defun space-next-moment! (space &optional (dt 1.0))
    (dolist (moving space)
        (dolist (static space)
            (unless (eql moving static)
                (update-vel! moving static)))
        (move-body! moving dt)))
